﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using BrainTechLLC.WPF;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using BrainTechLLC;
using System.Threading;

namespace ImageAppDataModels
{
    public partial class FileImage : BaseNotifyPropertyChangedUI, IHasFileBackingStore, INotifyPropertyChanged, IObjectLock, IFileImage
    {
        protected string _fileName;
        protected bool _deleted;
        protected long _fileSize;
        protected object _lockObjectFileInfo = new object();
        public DateTime _creationTime = DateTime.MinValue;

        public string FileName
        {
            get { return _fileName; }
            set
            {
                if (_fileName != value)
                {
                    if (!string.IsNullOrEmpty(_fileName))
                    {
                        lock (_lockObject)
                        {
                            _fileName = value;
                            MarkEverythingDirty(true);
                        }
                    }
                    OnPropertyChanged("FileName");
                }
            }
        }

        public void Rename(string newName)
        {
            if (FileName == newName)
                return;

            DataProvider.Copy(FileName, newName);
            DataProvider.Delete(FileName);
            
            FileName = newName;
        }

        public long FileSize
        {
            get
            {
                if (_fileSize == 0)
                {
                    lock (_lockObjectFileInfo)
                    {
                        if (_fileSize == 0)
                        {
                            byte[] bytes = _imageBytes;

                            if (bytes != null)
                            {
                                _fileSize = bytes.Length;
                            }
                            else
                            {
                                GetFileSizeAndCreationTime();
                            }
                        }
                    }
                }

                return _fileSize;
            }
            set
            {
                if (_fileSize != value)
                {
                    _fileSize = value;
                    OnPropertyChanged("FileSize");
                }
            }
        }

        public bool Deleted
        {
            get { return _deleted; }
            set
            {
                if (_deleted != value)
                {
                    _deleted = value;
                    OnPropertyChanged("Deleted");
                }
            }
        }

        public bool Delete()
        {
            try
            {
                DataProvider.Delete(_fileName);
                _deleted = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Debug.Write(ex.ToString());
                return false;
            }

            return true;
        }

        public DateTime GetFileSizeAndCreationTime()
        {
            if (_creationTime == DateTime.MinValue || _fileSize == 0)
            {
                bool setFileLength = false;
                bool setCreationTime = false;
                FileLocking.GetFileLock(_fileName);

                try
                {
                    EnterMonitor(_lockObjectFileInfo, 20);

                    try
                    {
                        if (_creationTime == DateTime.MinValue || _fileSize == 0)
                        {
                            FileInfo fi = new FileInfo(FileName);

                            if (_creationTime == DateTime.MinValue)
                            {
                                setCreationTime = true;
                                _creationTime = fi.CreationTime;
                            }

                            if (_fileSize == 0)
                            {
                                setFileLength = true;
                                _fileSize = fi.Length;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // WHAT TO DO HERE
                        Console.WriteLine(ex.ToString());
                    }
                    finally
                    {
                        Monitor.Exit(_lockObjectFileInfo);
                    }
                }
                finally
                {
                    FileLocking.ReleaseFileLock(_fileName);
                }

                if (setFileLength)
                {
                    OnPropertyChanged("FileSize");
                }

                if (setCreationTime)
                {
                    OnPropertyChanged("CreationTime");
                }
            }

            return _creationTime;
        }

        public DateTime CreationTime
        {
            get
            {
                if (_creationTime == DateTime.MinValue)
                {
                    lock (_lockObjectFileInfo)
                    {
                        if (_creationTime == DateTime.MinValue)
                        {
                            GetFileSizeAndCreationTime();
                        }
                    }
                }

                return _creationTime;
            }
            set
            {
                if (_creationTime != value)
                {
                    _creationTime = value;
                    OnPropertyChanged("CreationTime");
                }
            }
        }
    }
}
